package au.com.handsunited.service.impl;

import java.util.List;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import au.com.handsunited.dao.EntityDAO;
import au.com.handsunited.dao.InvitationDAO;
import au.com.handsunited.dao.MessageDAO;
import au.com.handsunited.dao.ProjectDAO;
import au.com.handsunited.model.BaseEntity;
import au.com.handsunited.model.Project;
import au.com.handsunited.model.User;
import au.com.handsunited.model.invitations.Invitation;
import au.com.handsunited.model.relationship.RelationshipStatus;
import au.com.handsunited.model.relationship.Role;
import au.com.handsunited.model.skill.Skill;
import au.com.handsunited.service.ProjectService;

/**
 *
 * @author arunda
 */
public class ProjectServiceImpl extends EntityServiceImpl implements
		ProjectService {

	private final ProjectDAO projectDAO;

	private static Logger logger = LoggerFactory
			.getLogger(ProjectServiceImpl.class);

	/**
	 *
	 * @param entityDAO
	 * @param messageDAO
	 *            TODO
	 * @param projectDAO
	 */
	public ProjectServiceImpl(EntityDAO entityDAO, MessageDAO messageDAO, InvitationDAO invitationDAO, ProjectDAO projectDAO) {

		super(entityDAO, messageDAO, invitationDAO);
		this.projectDAO = projectDAO;
	}


	/**
	 * @see au.com.handsunited.service.ProjectService#getProject(String)
	 */
	@Override
	public Project getProject(String id) {
		return getProject(Long.parseLong(id));
	}


	/**
	 * @see au.com.handsunited.service.ProjectService#getProject(java.lang.Long)
	 */
	@Override
	public Project getProject(Long id) {
		return (Project) getEntity(id);
	}


	/**
	 *
	 * @see au.com.handsunited.service.ProjectService#createProject(au.com.handsunited.model.Project,
	 *      au.com.handsunited.model.BaseEntity, BaseEntity)
	 */
	@Override
	public Project createProject(Project project, BaseEntity owner, BaseEntity creator) {

		if ((owner != null) && (creator != null)) {
			project = (Project) createEntity(project, owner, creator);
		}

		if (ProjectServiceImpl.logger.isDebugEnabled() && (owner != null)) {
			ProjectServiceImpl.logger.debug("{}[{}] created Project[{}]", new String[] {
					owner.getEntityType(), owner.getName(),
					project.getName() });
		}

		return project;
	}



	/**
	 * @see au.com.handsunited.service.ProjectService#searchForProjectsByCriteria(au.com.handsunited.model.Project)
	 */
	@Override
	public List<Project> searchForProjectsByCriteria(Project projectSearchCriteria) {

		return projectDAO.searchForProjectsByCriteria(projectSearchCriteria);
	}


	/**
	 * @see au.com.handsunited.service.ProjectService#searchForProjectsByKeywords(java.lang.String)
	 */
	@Override
	public List<Project> searchForProjectsByKeywords(String keywords) {
		return projectDAO.searchForProjectsByKeywords(keywords);
	}





	/**
	 * @see au.com.handsunited.service.ProjectService#getAllProjects()
	 */
	@Override
	public List<Project> getAllProjects() {
		return projectDAO.getProjects();
	}


	/**
	 * @see au.com.handsunited.service.ProjectService#updateProject(au.com.handsunited.model.Project,
	 *      au.com.handsunited.model.BaseEntity)
	 */
	@Override
	public Project updateProject(Project project, BaseEntity owner) {
		return (Project) updateEntity(project, owner);
	}


	/**
	 * @see au.com.handsunited.service.ProjectService#deleteProject(au.com.handsunited.model.Project,
	 *      au.com.handsunited.model.BaseEntity)
	 */
	@Override
	public boolean deleteProject(Project project, BaseEntity entity) {
		return false;
	}



	/**
	 * @see au.com.handsunited.service.ProjectService#addMemberToProject(au.com.handsunited.model.Project,
	 *      au.com.handsunited.model.BaseEntity)
	 */
	@Override
	public boolean addMemberToProject(Project project, BaseEntity entity) {

		return addMemberToNetwork(project, entity, Role.MEMBER, Role.UNKNOWN,
				RelationshipStatus.AWAITING_AUTHORISATION, RelationshipStatus.ACTION_PENDING);
	}



	/**
	 * @see au.com.handsunited.service.ProjectService#removeMemberFromProject(au.com.handsunited.model.Project,
	 *      au.com.handsunited.model.BaseEntity)
	 */
	@Override
	public boolean removeMemberFromProject(Project project, BaseEntity member) {

		return removeMemberFromNetwork(project, member);
	}




	/**
	 * @see au.com.handsunited.service.ProjectService#findProjectsNeedingSkills(java.util.List)
	 */
	@Override
	public List<Project> findProjectsNeedingSkills(List<Skill> skills) {
		return getAllProjects();
	}





	/**
	 * @see au.com.handsunited.service.ProjectService#findProjectsSimilarTo(au.com.handsunited.model.Project)
	 */
	@Override
	public List<Project> findProjectsSimilarTo(Project project) {
		return getAllProjects();
	}



	/**
	 * @see au.com.handsunited.service.ProjectService#inviteProject(au.com.handsunited.model.User, java.lang.String, java.lang.String, java.lang.String, java.lang.String)
	 */
	@Override
	public Invitation inviteProject(User user, String projectName,
			String contactName, String emailAddress, String message) {

		Invitation invitation = invitePotentialEntity(
				user, projectName, emailAddress, contactName, Invitation.INVITEE_TYPE_PROJECT, message);

		return invitation;
	}




	/**
	 * @see au.com.handsunited.service.ProjectService#inviteToProject(au.com.handsunited.model.Project, au.com.handsunited.model.User, List, java.lang.String, java.lang.String)
	 */
	@Override
	public Map<String, List<Invitation>> inviteToProject(
			Project project, User invitingUser, List<BaseEntity> invitees,
			String emailAddresses, String message) {

		return inviteTo(project, invitingUser, invitees, emailAddresses, message);

	}

}
